import { act } from '@testing-library/react';
import { QuoteResponse } from '@metamask/bridge-controller';

import { getMockConfirmStateForTransaction } from '../../../../../../test/data/confirmations/helper';
import {
  mockBridgeQuotes,
  mockSwapConfirmation,
} from '../../../../../../test/data/confirmations/contract-interaction';
import { renderHookWithConfirmContextProvider } from '../../../../../../test/lib/confirmations/render-helpers';
import { deleteDappSwapComparisonData } from '../../../../../store/actions';
import { Confirmation } from '../../../types/confirm';
import * as DappSwapContext from '../../../context/dapp-swap';
import { useDappSwapActions } from './useDappSwapActions';

jest.mock('../../../../../store/actions', () => ({
  deleteDappSwapComparisonData: jest.fn(),
}));

const mockCaptureSwapSubmit = jest.fn();
jest.mock('./useDappSwapComparisonMetrics', () => ({
  useDappSwapComparisonMetrics: () => ({
    captureSwapSubmit: mockCaptureSwapSubmit,
  }),
}));

async function runHook(mockConfirmation?: Confirmation) {
  const response = renderHookWithConfirmContextProvider(
    useDappSwapActions,
    getMockConfirmStateForTransaction(
      mockConfirmation ?? (mockSwapConfirmation as Confirmation),
    ),
  );

  await act(async () => {
    // Ignore
  });

  return response.result.current;
}

describe('useDappSwapActions', () => {
  describe('updateSwapWithQuoteDetailsIfRequired', () => {
    it('updates transactionMeta with MM quote if available', async () => {
      jest.spyOn(DappSwapContext, 'useDappSwapContext').mockReturnValue({
        selectedQuote: mockBridgeQuotes[0] as unknown as QuoteResponse,
        setSelectedQuote: jest.fn(),
        setQuotedSwapDisplayedInInfo: jest.fn(),
        isQuotedSwapDisplayedInInfo: true,
      } as unknown as ReturnType<typeof DappSwapContext.useDappSwapContext>);

      const mockTransactionMeta = { txParams: {} };
      const { updateSwapWithQuoteDetailsIfRequired } = await runHook();
      updateSwapWithQuoteDetailsIfRequired(mockTransactionMeta);

      expect(mockTransactionMeta).toStrictEqual(
        expect.objectContaining({
          batchTransactions: [
            {
              data: '0x095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3000000000000000000000000000000000000000000000000000000000007a120',
              gas: '0xf67f',
              isAfter: false,
              maxFeePerGas: undefined,
              maxPriorityFeePerGas: undefined,
              to: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
              type: 'swapApproval',
              value: '0x0',
            },
          ],
          batchTransactionsOptions: {},
          nestedTransactions: undefined,
          txParams: {
            data: '0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000069274d750000000000000000000000000000000000000000000000000000000000000002100c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000004070c100e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000007a1200000000000000000000000000000000000000000000000000000000000000060000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000058c51ee8998e8ef06362df26a0d966bbd0cf511300000000000000000000000000000000000000000000000000000000000013880000000000000000000000000000000000000000000000000000000000000060000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000005206d14bfa10bd18989038fe628a79a135f2ee2f0000000000000000000000000000000000000000000000000000000000000000',
            gas: '0x619f7',
            to: '0x9dDA6Ef3D919c9bC8885D5560999A3640431e8e6',
            value: '0x0',
          },
        }),
      );
      expect(mockCaptureSwapSubmit).toHaveBeenCalled();
    });
  });

  describe('onDappSwapCompleted', () => {
    it('should delete the dapp swap comparison data and capture the swap submit', async () => {
      jest.spyOn(DappSwapContext, 'useDappSwapContext').mockReturnValue({
        selectedQuote: undefined,
        setSelectedQuote: jest.fn(),
        setQuotedSwapDisplayedInInfo: jest.fn(),
      } as unknown as ReturnType<typeof DappSwapContext.useDappSwapContext>);

      const { onDappSwapCompleted } = await runHook();
      onDappSwapCompleted();

      expect(deleteDappSwapComparisonData).toHaveBeenCalledWith(
        'f8172040-b3d0-11f0-a882-3f99aa2e9f0c',
      );
    });
  });
});
